DOC GOI PHUT GIAY
//****************************************************************************** // CAC CHUONG TRINH CON CHO I2C //****************************************************************************** void I2C_start() //ham khoi dong I2C { SCL = 1; SCL = 0; SDA = 1; SCL = 1; SDA = 0; SCL = 0; } void I2C_stop() { SCL = 1; //keo chan SDA len 1 SCL = 0; SDA = 0; SCL = 1; SDA = 1; } unsigned char I2C_write(unsigned char dat)//ham ghi 1 byte du lieu vao DS1307 { unsigned char i; for (i=0;i<8;i++) { SDA = (dat & 0x80); ///? 1:0; SCL=1; SCL=0; dat<<=1; } SCL = 1; SCL = 0; return dat; } unsigned char I2C_read(void) { bit rd_bit; unsigned char i, dat; dat = 0x00; for(i=0;i<8;i++) /* For loop read data 1 byte */ { SCL = 1; rd_bit = SDA; /* Keep for check acknowledge */ dat = dat<<1; dat = dat | rd_bit; /* Keep bit data in dat */ SCL = 0; /* Clear SCL */ } return dat; } // CAC CHUONG TRINH CON CHO DS1307 //****************************************************************************** unsigned char DS1307_read(unsigned char addr) { unsigned int temp,ret; I2C_start(); /* Start i2c bus */ I2C_write(0xD0); /* Connect to DS1307 */ I2C_write(addr); /* Request RAM address on DS1307 */ I2C_start(); /* Start i2c bus */ I2C_write(0XD1); /* Connect to DS1307 for Read */ ret = I2C_read(); /* Receive data */ I2C_stop(); //********************************************************** temp = ret; /*BCD to HEX*/ ret = (((ret/16)*10)+ (temp & 0x0f)); /*for Led 7seg*/ //********************************************************** return ret; } void DS1307_Write(unsigned char addr,unsigned char dat) { unsigned int temp; //********************************************** temp = dat ; /*HEX to BCD*/ dat = (((dat/10)*16)|(temp %10)); /*for Led 7seg*/ //********************************************** I2C_start(); /* Start i2c bus */ I2C_write(0XD0); /* Connect to DS1307 */ I2C_write(addr); /* Request RAM address on DS1307 */ I2C_write(dat); /* Connect to DS1307 for Read */ I2C_stop(); } void Read_DS1307() { sec = DS1307_read(SEC); //doc giay tu DS1307 min = DS1307_read(MIN); //doc phut tu DS1307 hour = DS1307_read(HOUR); //doc gio tu DS1307 day = DS1307_read(DAY); //doc ngay tu DS1307 date = DS1307_read(DATE); //doc thu tu DS1307 month = DS1307_read(MONTH); //doc thang tu DS1307 year = DS1307_read(YEAR); //doc nam tu DS1307 } void Write_DS1307() { DS1307_Write(SEC,sec); //ghi du lieu vao thanh ghi giay DS1307_Write(MIN,min); //ghi du lieu vao thanh ghi phut DS1307_Write(HOUR,hour); //ghi du lieu vao thanh ghi gio DS1307_Write(DAY,day); //ghi du lieu vao thanh ghi ngay DS1307_Write(DATE,date); //ghi du lieu vao thanh ghi thu DS1307_Write(MONTH,month); //ghi du lieu vao thanh ghi thang DS1307_Write(YEAR,year); //ghi du lieu vao thanh ghi nam }
#define RTC_SDA p0.0
#define RTC_SCL p0.1
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)
BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);
void ds1307_init(void)
{
BYTE seconds = 0;
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x00); // REG 0
i2c_start();
i2c_write(0xD1); // RD from RTC
seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
i2c_stop();
seconds &= 0x7F;
delay_us(3);
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x00); // REG 0
i2c_write(bin2bcd(seconds)); // Start oscillator with current "seconds value
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x07); // Control Register
i2c_write(0x80); // Disable squarewave output pin
i2c_stop();
}
void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
sec &= 0x7F;
hr &= 0x3F;
i2c_start();
i2c_write(0xD0); // I2C write address
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_write(bin2bcd(sec)); // REG 0
i2c_write(bin2bcd(min)); // REG 1
i2c_write(bin2bcd(hr)); // REG 2
i2c_write(bin2bcd(dow)); // REG 3
i2c_write(bin2bcd(day)); // REG 4
i2c_write(bin2bcd(mth)); // REG 5
i2c_write(bin2bcd(year)); // REG 6
i2c_write(0x80); // REG 7 - Disable squarewave output pin
i2c_stop();
}
void DS1307_Write(unsigned char addr,unsigned char dat)
{
unsigned int temp;
//**********************************************
temp = dat ; /*HEX to BCD*/
dat = (((dat/10)*16)|(temp %10)); /*for Led 7seg*/
//**********************************************
I2C_start(); /* Start i2c bus */
I2C_write(0XD0); /* Connect to DS1307 */
I2C_write(addr); /* Request RAM address on DS1307 */
I2C_write(dat); /* Connect to DS1307 for Read */
I2C_stop();
}
void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x03); // Start at REG 3 - Day of week
i2c_start();
i2c_write(0xD1);
dow = bcd2bin(i2c_read() & 0x7f); // REG 3
day = bcd2bin(i2c_read() & 0x3f); // REG 4
mth = bcd2bin(i2c_read() & 0x1f); // REG 5
year = bcd2bin(i2c_read(0)); // REG 6
i2c_stop();
}
void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_start();
i2c_write(0xD1);
sec = bcd2bin(i2c_read() & 0x7f);
min = bcd2bin(i2c_read() & 0x7f);
hr = bcd2bin(i2c_read(0) & 0x3f);
i2c_stop();
}
BYTE bin2bcd(BYTE binary_value)
{
BYTE temp;
BYTE retval;
temp = binary_value;
retval = 0;
while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}
return(retval);
}
// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
BYTE temp;
temp = bcd_value;
// Shifting upper digit right by 1 is same as multiplying by 8.
temp >>= 1;
// Isolate the bits for the upper digit.
temp &= 0x78;
// Now return: (Tens * 8) + (Tens * 2) + Ones
return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
void setup();
VOID chinh() ;
void chinhgio();
void chinhphut();
void chinhgiay();
void dich2(int8 data);
void hienthi();
int8 mode;
int8 i,k,c,d,l,m,h,n,j,w,x,gioihantren,gioihanduoi,nho1 ;
int8 day,mth,year,dow,hr,min,sec,tam;
//=====Chuong trinh ngat=============================
#int_ext
ext_interrupt()
{
mode++;
if (mode==4)
{
mode=0;
ds1307_set_date_time(day,mth,year,dow,hr,min,sec);
}
}
co de dung trong chuong chinh chinh
//==========khoi dong ds1307=========================
ds1307_init();
delay_ms(100);
ds1307_set_date_time(2,3,2012,5,17,59,50);
output_low(clk_led);
output_low(latch_led);
delay_ms(1);
while (1)
{
switch(mode)
{
case 1:
chinhgio();break;
}
}
}
//==========dich2==================
//ht_data,clk_led
void dich2(int8 data)
{
int i;
for (i=0;i<8;i++)
{
output_bit(ht_data,shift_left(&data,1,1));
output_high(clk_led);
delay_cycles(10);
output_low(clk_led);
delay_cycles(10);
}
output_high(latch_led);
delay_cycles(10);
output_low(latch_led);
delay_cycles(10);
}
/////////////////////////////////////
VOID chinh()
{
if(UP_BUT==0)
{
delay_ms(100);
tam ++;
if (tam >gioihantren)
tam=gioihanduoi;
}
if (DOWN_BUT==0)
{
tam --;
delay_ms(100);
if (tam <gioihanduoi)
tam=gioihantren;
}
}
void chinhgio()
{
ds1307_get_time(hr,min,sec);
tam=hr;
if(up_but==0)
{
tam++;
hr=tam;
}
hienthi();
}
void chinhphut()
{
tam=min;
gioihanduoi=00;
gioihantren=59;
chinh();
min=tam;
}
void chinhgiay()
{
tam=sec;
gioihanduoi=00;
gioihantren=59;
chinh();
sec=tam;
}
void hienthi()
{
//======hien gio==========
for(i=3,n=0;i<9,n<6;i++,n++)
{
output_d(i);
dich2(ma_code[n+hr/10*6]);
delay_us(1000);
}
for(i=9,k=0;i<16,k<6;i++,k++)
{
output_d(i);
dich2(ma_code[k+hr%10*6]);
delay_us(1000);
}
//=====hien phut============
for(i=18,l=0;i<25,l<6;i++,l++)
{
output_d(i);
dich2(ma_code[l+min/10*6]);
delay_us(1000);
}
for(i=24,m=0;i<31,m<6;i++,m++)
{
output_d(i);
dich2(ma_code[m+min%10*6]);
delay_us(1000);
}
/////////////////giay
for(i=33,c=0;i<39,c<6;i++,c++)
{
output_d(i);
dich2(ma_code[c+sec/10*6]);
delay_us(1000);
}
for(i=39,d=0;i<46,d<6;i++,d++)
{
output_d(i);
dich2(ma_code[d+sec%10*6]);
delay_us(1000);
}
}
//////////////////
#include "89c51x.h"
#FUSES NOWDT,HS, NOPROTECT,NOLVP, NOWRT
#use delay(clock=20000000)
#define ht_data p2.0//chan14 cua 74595
#define clk_led p2.1//chan11
#define latch_led p2.2 //chan 12
#DEFINE UP_BUT INPUT(p3.1) //chinh tang thoi gian
#DEFINE DOWN_BUT INPUT(p3.2) // giam thoi gian
////////////////////////////////////////////////////////////////////////////////
/// DS1307.C ///
/// Driver for Real Time Clock ///
/// ///
/// ds1307_init() - Enable oscillator without clearing the seconds register -///
/// used when PIC loses power and DS1307 run from 3V BAT ///
/// - Disable squarewave output ///
/// ///
/// ds1307_set_date_time(day,mth,year,dow,hour,min,sec ) Set the date/time ///
/// ///
/// ds1307_get_date(day,mth,year,dow) Get the date ///
/// ///
/// ds1307_get_time(hr,min,sec) Get the time ///
/// ///
////////////////////////////////////////////////////////////////////////////////
#define RTC_SDA p0.0 //giao tiep ds1307
#define RTC_SCL p0.1 //chuyen du lieu vao ds1307
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)
BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);
void ds1307_init(void)
{
BYTE seconds = 0;
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x00); // REG 0
i2c_start();
i2c_write(0xD1); // RD from RTC
seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
i2c_stop();
seconds &= 0x7F;
delay_us(3);
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x00); // REG 0
i2c_write(bin2bcd(seconds)); // Start oscillator with current "seconds value
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x07); // Control Register
i2c_write(0x80); // Disable squarewave output pin
i2c_stop();
}
void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
sec &= 0x7F;
hr &= 0x3F;
i2c_start();
i2c_write(0xD0); // I2C write address
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_write(bin2bcd(sec)); // REG 0
i2c_write(bin2bcd(min)); // REG 1
i2c_write(bin2bcd(hr)); // REG 2
i2c_write(bin2bcd(dow)); // REG 3
i2c_write(bin2bcd(day)); // REG 4
i2c_write(bin2bcd(mth)); // REG 5
i2c_write(bin2bcd(year)); // REG 6
i2c_write(0x80); // REG 7 - Disable squarewave output pin
i2c_stop();
}
void DS1307_Write(unsigned char addr,unsigned char dat)
{
unsigned int temp;
//**********************************************
temp = dat ; /*HEX to BCD*/
dat = (((dat/10)*16)|(temp %10)); /*for Led 7seg*/
//**********************************************
I2C_start(); /* Start i2c bus */
I2C_write(0XD0); /* Connect to DS1307 */
I2C_write(addr); /* Request RAM address on DS1307 */
I2C_write(dat); /* Connect to DS1307 for Read */
I2C_stop();
}
void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x03); // Start at REG 3 - Day of week
i2c_start();
i2c_write(0xD1);
dow = bcd2bin(i2c_read() & 0x7f); // REG 3
day = bcd2bin(i2c_read() & 0x3f); // REG 4
mth = bcd2bin(i2c_read() & 0x1f); // REG 5
year = bcd2bin(i2c_read(0)); // REG 6
i2c_stop();
}
void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_start();
i2c_write(0xD1);
sec = bcd2bin(i2c_read() & 0x7f);
min = bcd2bin(i2c_read() & 0x7f);
hr = bcd2bin(i2c_read(0) & 0x3f);
i2c_stop();
}
BYTE bin2bcd(BYTE binary_value)
{
BYTE temp;
BYTE retval;
temp = binary_value;
retval = 0;
while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}
return(retval);
}
// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
BYTE temp;
temp = bcd_value;
// Shifting upper digit right by 1 is same as multiplying by 8.
temp >>= 1;
// Isolate the bits for the upper digit.
temp &= 0x78;
// Now return: (Tens * 8) + (Tens * 2) + Ones
return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
void setup();
VOID chinh() ;
void chinhgio();
void chinhphut();
void chinhgiay();
void dich2(int8 data);
void hienthi();
int8 mode;
int8 i,k,c,d,l,m,h,n,j,w,x,gioihantren,gioihanduoi,nho1 ;
int8 day,mth,year,dow,hr,min,sec,tam;
//=====Chuong trinh ngat=============================
#int_ext
ext_interrupt()
{
mode++;
if (mode==4)
{
mode=0;
ds1307_set_date_time(day,mth,year,dow,hr,min,sec);
}
}
byte const ma_code[]={ 0x83,0x5D,0x6D,0x75,0x83,0xFF,//0 0
0xDD,0xBD,0x01,0xFD,0xFD,0xFF,//1 6
0xB1,0x6D,0x6D,0x6D,0x9D,0xFF,//2 12
0xBB,0x7D,0x6D,0x6D,0x93,0xFF,//3 18
0xE7,0xD7,0xB7,0x01,0xF7,0xFF,//4 24
0x1B,0x5D,0x5D,0x5D,0x63,0xFF,//5 30
0xC3,0xAD,0x6D,0x6D,0xF3,0xFF,//6 36
0x7F,0x71,0x6F,0x5F,0x3F,0xFF,//7 42
0x93,0x6D,0x6D,0x6D,0x93,0xFF,//8 48
0x9B,0x6D,0x6D,0x6D,0x83,0xFF,//9 54
};
/////////////////////////////////////////////////
// -------------------chuong trinh chinh -------------------
void main()
{
set_tris_a(0);
set_tris_b(0b00001111);
set_tris_c(0);
set_tris_d(0);
set_tris_e(0);
//=====Khai Bao Ngat=================================
enable_interrupts(global); // ngat toan cuc
enable_interrupts(int_ext); // ngat ngoai RB0
ext_int_edge(H_to_L); // Ngat canh suon am
mode=0;
//==========khoi dong ds1307=========================
ds1307_init();
delay_ms(100);
ds1307_set_date_time(2,3,2012,5,17,59,50);
output_low(clk_led);
output_low(latch_led);
delay_ms(1);
while (1)
{
switch(mode)
{
case 1:
chinhgio();break;
}
}
}
//==========dich2==================
//ht_data,clk_led
void dich2(int8 data)
{
int i;
for (i=0;i<8;i++)
{
output_bit(ht_data,shift_left(&data,1,1));
output_high(clk_led);
delay_cycles(10);
output_low(clk_led);
delay_cycles(10);
}
output_high(latch_led);
delay_cycles(10);
output_low(latch_led);
delay_cycles(10);
}
/////////////////////////////////////
VOID chinh()
{
if(UP_BUT==0)
{
delay_ms(100);
tam ++;
if (tam >gioihantren)
tam=gioihanduoi;
}
if (DOWN_BUT==0)
{
tam --;
delay_ms(100);
if (tam <gioihanduoi)
tam=gioihantren;
}
}
void chinhgio()
{
ds1307_get_time(hr,min,sec);
tam=hr;
if(up_but==0)
{
tam++;
hr=tam;
}
hienthi();
}
void chinhphut()
{
tam=min;
gioihanduoi=00;
gioihantren=59;
chinh();
min=tam;
}
void chinhgiay()
{
tam=sec;
gioihanduoi=00;
gioihantren=59;
chinh();
sec=tam;
}
void hienthi()
{
//======hien gio==========
for(i=3,n=0;i<9,n<6;i++,n++)
{
output_d(i);
dich2(ma_code[n+hr/10*6]);
delay_us(1000);
}
for(i=9,k=0;i<16,k<6;i++,k++)
{
output_d(i);
dich2(ma_code[k+hr%10*6]);
delay_us(1000);
}
//=====hien phut============
for(i=18,l=0;i<25,l<6;i++,l++)
{
output_d(i);
dich2(ma_code[l+min/10*6]);
delay_us(1000);
}
for(i=24,m=0;i<31,m<6;i++,m++)
{
output_d(i);
dich2(ma_code[m+min%10*6]);
delay_us(1000);
}
/////////////////giay
for(i=33,c=0;i<39,c<6;i++,c++)
{
output_d(i);
dich2(ma_code[c+sec/10*6]);
delay_us(1000);
}
for(i=39,d=0;i<46,d<6;i++,d++)
{
output_d(i);
dich2(ma_code[d+sec%10*6]);
delay_us(1000);
}
}